﻿using System;
using System.Threading;
using OmegaBot;

namespace drone_cc
{

    public class dronePaladinCombat : CombatClass
    {
        //TODO:

        #region properties / class setup
        //combat spells
        SpellKeyDefinition crusaderstrike;
        SpellKeyDefinition divinestorm;
        SpellKeyDefinition consecration;
        SpellKeyDefinition hammerofwrath;
        SpellKeyDefinition exorsicm;
        SpellKeyDefinition judgmentoflight;
        SpellKeyDefinition judgmentofwisdom;
        SpellKeyDefinition judgmentofjustice;
        SpellKeyDefinition handofreckoning;
        SpellKeyDefinition avengingwrath;

        //buffs
        SpellKeyDefinition sealofcommand;
        SpellKeyDefinition sealofrighteousness;
        SpellKeyDefinition sealofvengeance;
        SpellKeyDefinition blessingofmight;
        SpellKeyDefinition blessingofkings;
        SpellKeyDefinition blessingofwisdom;
        SpellKeyDefinition retributionaura;
        SpellKeyDefinition devotionaura;
        SpellKeyDefinition divineplea;
        SpellKeyDefinition theartofwar;

        //heals & decurse
        SpellKeyDefinition flashoflight;
        SpellKeyDefinition holylight;
        SpellKeyDefinition cleanse;
        SpellKeyDefinition purify;
        SpellKeyDefinition layonhands;
        SpellKeyDefinition divineshield;
        SpellKeyDefinition divineprotection;

        //mounting 
        SpellKeyDefinition crusaderaura;

        public IniManager Ini;

        public override string CombatClassName { get { return "drone-cc paladin"; } }

        public override void CreateSetup()
        {
            Ini = new IniManager("drone-cc.ini");
            Ini.SetComment("drone-cc.ini\r\n\r\nconfiguration for drone-cc");

            //combat spells
            Ini.Set("paladin", "usecrusaderstrike", "true");
            Ini.Set("paladin", "usedivinestorm", "true");
            Ini.Set("paladin", "useconsecration", "false");
            Ini.Set("paladin", "consecrationonadds", "false");
            Ini.Set("paladin", "usehammerofwrath", "true");
            Ini.Set("paladin", "usehandofreckoning", "true");

            //smart art of war
            Ini.Set("paladin", "enablesmartartofwar", "false");
            Ini.Set("paladin", "useexorcism", "true");
            Ini.Set("paladin", "useflashoflight", "true");
            Ini.Set("paladin", "flashpercent", 60);

            //smart judgments
            Ini.Set("paladin", "enablesmartjudgments", "false");
            Ini.Set("paladin", "usejudgmentofjustice", "true");
            Ini.Set("paladin", "usejudgmentofwisdom", "true");
            Ini.Set("paladin", "wisdompercent", 20);

            //buffs / heals
            Ini.Set("paladin", "useavengingwrath", "true");
            Ini.Set("paladin", "useblessing", "might");
            Ini.Set("paladin", "useaura", "retribution");
            Ini.Set("paladin", "useseal", "command");
            Ini.Set("paladin", "usedivineplea", "false");
            Ini.Set("paladin", "uselightheal", "true");
            Ini.Set("paladin", "lighthealpercent", 60);
            Ini.Set("paladin", "usebigheal", "true");
            Ini.Set("paladin", "bighealpercent", 40);

            //mount
            Ini.Set("paladin", "usemount", "false");
            Ini.Set("paladin", "skiplootcheck", "false");
            Ini.Set("paladin", "mountdistance", "40");
            Ini.Set("paladin", "mountusecrusaderaura", "false");

            Ini.Set("paladin", "combineitems", "false");
            Ini.Set("paladin", "openclams", "false");
            Ini.Set("paladin", "enablepvp", "false");

            Ini.Load();
            Ini.Save();
        }

        // Make our special setup window and return it so it can be shown:
        protected override ClassSetupPanel CreateSetupPanel()
        {
            return new dronePaladinSetup(this);
        }

        protected override void SetupKeys()
        {
            Log.WriteLine("Drone is setting up spell keys");
            // combat spells
            crusaderstrike = SpellKeys.CreateFromHostileSpell("crusaderstrike", 35395);
            divinestorm = SpellKeys.CreateFromHostileSpell("divinestorm", 53385);
            consecration = SpellKeys.CreateFromHostileSpell("consecration", 26573);
            hammerofwrath = SpellKeys.CreateFromHostileSpell("hammerofwrath", 24275);
            exorsicm = SpellKeys.CreateFromHostileSpell("exorsicm", 879);
            judgmentoflight = SpellKeys.CreateFromHostileSpell("judgmentoflight", 20271);
            judgmentofwisdom = SpellKeys.CreateFromHostileSpell("judgmentofwisdom", 53408);
            judgmentofjustice = SpellKeys.CreateFromHostileSpell("judgmentofjustice", 53407);
            handofreckoning = SpellKeys.CreateFromHostileSpell("handofreckoning", 62124);

            // buffs / heals / decurse
            flashoflight = SpellKeys.CreateFromSpell("flashoflight", 19750);
            holylight = SpellKeys.CreateFromSpell("holylight", 635);
            cleanse = SpellKeys.CreateFromSpell("cleanse", 4987);
            purify = SpellKeys.CreateFromSpell("purify", 1152);
            sealofcommand = SpellKeys.CreateFromSpell("sealofcommand", 20375);
            sealofrighteousness = SpellKeys.CreateFromSpell("sealofrighteousness", 21084);
            sealofvengeance = SpellKeys.CreateFromSpell("sealofvengeance", "31801 53736");
            blessingofmight = SpellKeys.CreateFromSpell("blessingofmight", 19740);
            blessingofkings = SpellKeys.CreateFromSpell("blessingofkings", 20217);
            blessingofwisdom = SpellKeys.CreateFromSpell("blessingofwisdom", 19742);
            retributionaura = SpellKeys.CreateFromSpell("retributionaura", "7294 10298 10299 10300 10301 27150 54043");
            devotionaura = SpellKeys.CreateFromSpell("devotionaura", "465 10290 643 10291 1032 10292 10293 27149 48941 48942");
            avengingwrath = SpellKeys.CreateFromSpell("avengingwrath", 31884);
            divineplea = SpellKeys.CreateFromSpell("divineplea", 54428);
            layonhands = SpellKeys.CreateFromSpell("layonhands", 633);
            divineshield = SpellKeys.CreateFromSpell("divineshield", 642);
            divineprotection = SpellKeys.CreateFromSpell("divineprotection", 498);
            theartofwar = SpellKeys.CreateFromSpell("theartofwar", "59578 53489");

            //mounts
            DroneCombatClassUtilties.setupMountSpellKeys(SpellKeys);
            crusaderaura = SpellKeys.CreateFromSpell("crusaderaura", 32223);

            // Set up normal options for these spells:
            crusaderstrike.SetDefaultOptions(CastOptions.ChainCast);
            divinestorm.SetDefaultOptions(CastOptions.ChainCast);
            consecration.SetDefaultOptions(CastOptions.ChainCast);
            hammerofwrath.SetDefaultOptions(CastOptions.ChainCast);
            judgmentoflight.SetDefaultOptions(CastOptions.ChainCast);
            flashoflight.SetDefaultOptions(CastOptions.ExpectCastBar | CastOptions.SelfTarget);
            holylight.SetDefaultOptions(CastOptions.ExpectCastBar | CastOptions.SelfTarget);
        }
        #endregion

        #region Resting / Healing / Buffs

        void EnterAura(SpellKeyDefinition theSpell)
        {
            if (theSpell.canCast())
            {
                theSpell.Cast();
            }
        }

        bool InRetributionAura
        {
            get
            {
                if (retributionaura.IsDefined)
                {
                    return Me.HasBuff(retributionaura.Key.SpellID);
                }

                return false;
            }
        }

        bool InDevotionAura
        {
            get
            {
                if (devotionaura.IsDefined)
                {
                    return Me.HasBuff(devotionaura.Key.SpellID);
                }

                return false;
            }
        }

        bool InCrusaderAura
        {
            get
            {
                if (crusaderaura.IsDefined)
                {
                    return Me.HasBuff(crusaderaura.Key.SpellID);
                }

                return true;
            }
        }

        public override bool CanDrink
        {
            get
            {
                return true;
            }
        }

        public override bool DoLightHeal()
        {
            Log.WriteLine("LightHeal");
            if (flashoflight.canCast())
            {
                Input.ReleaseAllKeys();
                flashoflight.Cast(CastOptions.ExpectCastBar | CastOptions.SelfTarget);
                return true;
            }
            else
            {
                return false;
            }
        }

        public override bool DoBigHeal()
        {
            Log.WriteLine("BigHeal");
            if (holylight.canCast())
            {
                Input.ReleaseAllKeys();
                holylight.Cast(CastOptions.ExpectCastBar | CastOptions.SelfTarget);
                return true;
            }
            else
            {
                return false;
            }
        }

        public override void Buff()
        {
            string useseal = Ini.GetString("paladin", "useseal");
            string useaura = Ini.GetString("paladin", "useaura");
            string useblessing = Ini.GetString("paladin", "useblessing");

            //Item Combine
            if (DroneCombatClassUtilties.needCombine() &&
                Ini.GetBoolean("paladin", "combineitems", false))
            {
                DroneCombatClassUtilties.combineItems(this.Input);
            }

            //open clams
            if (DroneCombatClassUtilties.needOpenClams() &&
                Ini.GetBoolean("paladin", "openclams", false))
            {
                DroneCombatClassUtilties.combineItems(this.Input);
            }

            //mount section
            if (!Me.isMounted() &&
                Ini.GetBoolean("paladin", "usemount", false))
            {
                if (Me.mustMount(Ini, "paladin"))
                {
                    Me.mountUp(this.Input);

                    //Cast Crusader Aura
                    if (!InCrusaderAura && Ini.GetBoolean("paladin", "mountusecrusaderaura", true))
                    {
                        Input.ReleaseAllKeys();
                        EnterAura(crusaderaura);
                        Log.WriteLine("Entering Crusader Aura!");
                    }
                }
            }

            //seal selection
            if (sealofrighteousness.IsDefined && useseal.Equals("righteousness"))
            {
                if (sealofrighteousness.ConsiderBuff())
                    return;
            }
            if (sealofcommand.IsDefined && useseal.Equals("command"))
            {
                if (sealofcommand.ConsiderBuff())
                    return;
            }
            if (sealofvengeance.IsDefined && useseal.Equals("vengeance"))
            {
                if (sealofvengeance.ConsiderBuff())
                    return;
            }

            //blessing selection
            if (blessingofmight.IsDefined && useblessing.Equals("might"))
            {
                if (blessingofmight.ConsiderBuff())
                    return;
            }
            if (blessingofkings.IsDefined && useblessing.Equals("kings"))
            {
                if (blessingofkings.ConsiderBuff())
                    return;
            }
            if (blessingofwisdom.IsDefined && useblessing.Equals("wisdom"))
            {
                if (blessingofwisdom.ConsiderBuff())
                    return;
            }

            //aura selection
            if (!InRetributionAura && retributionaura.IsDefined && useaura.Equals("retribution") && !Me.isMounted())
            {
                EnterAura(retributionaura);
            }
            if (!InDevotionAura && devotionaura.IsDefined && useaura.Equals("devotion") && !Me.isMounted())
            {
                EnterAura(devotionaura);
            }

            //decurse
            if (ConsiderRemoveDebuff(cleanse, BuffType.Poison, false))
            {
                return;
            }
            if (ConsiderRemoveDebuff(cleanse, BuffType.Disease, false))
            {
                return;
            }
            if (ConsiderRemoveDebuff(cleanse, BuffType.Magic, false))
            {
                return;
            }

        }

        bool HasCurableDebuff
        {
            get
            {
                Buff[] buffs = Me.GetUnitBuffs();

                foreach (Buff one in buffs)
                {
                    if (one.IsHarmful && one.SecondsLeft > 30)
                    {
                        if ((one.BuffType == BuffType.Magic && cleanse.IsDefined) ||
                            (one.BuffType == BuffType.Poison && cleanse.IsDefined) ||
                            (one.BuffType == BuffType.Disease && cleanse.IsDefined))
                        {
                            return true;
                        }
                    }
                }
                return false;
            }
        }

        void CureAllDebuffs()
        {
            Buff[] buffs = Me.GetUnitBuffs();
            bool foundDebuff = false;

            foreach (Buff one in buffs)
            {
                if (one.IsHarmful && one.SecondsLeft > 30)
                {
                    if (one.BuffType == BuffType.Magic ||
                        one.BuffType == BuffType.Poison ||
                        one.BuffType == BuffType.Disease)
                    {
                        foundDebuff = true;
                    }
                }
            }
            if (foundDebuff && cleanse.canCast())
            {
                cleanse.Cast();
            }
        }
        #endregion

        #region Combat
        protected override CombatResult Combat(GameUnit Target)
        {
            Ticker healSpam = new Ticker(5000);

            if (Me.isMounted())
            {
                Me.dismount();
                string useaura = Ini.GetString("paladin", "useaura");

                if (InCrusaderAura)
                {
                    if (retributionaura.IsDefined && useaura.Equals("retribution"))
                    {
                        EnterAura(retributionaura);
                    }
                    if (devotionaura.IsDefined && useaura.Equals("devotion"))
                    {
                        EnterAura(devotionaura);
                    }
                    Log.WriteLine("Returning to fight Aura!");
                }

            }

            if (!Target.IsMob && !Ini.GetBoolean("paladin", "enablepvp", false))
            {
                Log.WriteLine("Attempted to Target player on accident!");
                return CombatResult.Retry;
            }

            // Close Distance before Combat
            if (Ini.GetBoolean("paladin", "usehandofreckoning", true))
            {
                if (Target.Distance > 5 && Target.TargetGUID == 0)
                {
                    if (Target.Distance > 28)
                    {
                        Target.GoTo(28, true);
                    }
                    if (handofreckoning.canCast())
                    {
                        handofreckoning.Cast(CastOptions.FastReturn);
                    }
                    Target.GoTo();
                }
            }
            else
            {
                if (Target.Distance > 10)
                {
                    Target.GoTo(10, true);
                }
                if (judgmentoflight.canCast())
                {
                    judgmentoflight.Cast(CastOptions.FastReturn);
                }
            }
            Target.Face();
            Target.GoTo();
            //End Close Distance Before Combat


            Input.ReleaseAllKeys();
            // Main loop!
            while (true)
            {
                GameUnit extra = GameUnit.GetNearestAttacker(Target.GUID);
                CombatResult result = CheckCommonCombatResult(Target, false);

                Thread.Sleep(107);
                if (result != CombatResult.Unknown)
                {
                    return result;
                }

                // Adjust Ourselves
                if (Target.Distance > 5.0)
                {
                    Target.GoTo();
                    continue;
                }
                else
                {
                    Target.Face();
                    Target.AdjustForMelee(true);
                }

                //Healing Code
                if (Me.Health < System.Convert.ToDouble(Ini.GetString("paladin", "lighthealpercent")) / 100 &&
                    Ini.GetBoolean("paladin", "uselightheal", true))
                {
                    DoLightHeal();
                }
                if (Me.Health < System.Convert.ToDouble(Ini.GetString("paladin", "bighealpercent")) / 100 &&
                    Ini.GetBoolean("paladin", "usebigheal", true))
                {
                    DoBigHeal();
                }
                if (Me.Health < .15)
                {
                    //emergengy measures
                    if (layonhands.canCast())
                    {
                        layonhands.Cast();
                        continue;
                    }
                    if (divineshield.canCast())
                    {
                        divineshield.Cast();
                        DoBigHeal();
                        continue;
                    }
                    if (divineprotection.canCast())
                    {
                        divineprotection.Cast();
                        DoBigHeal();
                        continue;
                    }
                }//End Healing Code

                //Avenging Wrath
                if (NeedMoreDPS)
                {
                    if (avengingwrath.canCast() && Ini.GetBoolean("paladin", "useavengingwrath", true))
                    {
                        avengingwrath.Cast();
                        continue;
                    }
                }//End Avenging Wrath

                //Divine Plea
                if (Me.Mana > .85)
                {
                    if (divineplea.canCast() && Ini.GetBoolean("paladin", "usedivineplea", true))
                    {
                        divineplea.Cast();
                        continue;
                    }
                }//End Divine Plea

                //Crusader Strike
                if (crusaderstrike.canCast() && Ini.GetBoolean("paladin", "usecrusaderstrike", true))
                {
                    crusaderstrike.Cast();
                    continue;
                }//End Crusader Strike

                //Smart judgment
                if (Ini.GetBoolean("paladin", "enablesmartjudgments", true))
                {
                    //Log.WriteLine("Smart Judge( Mana: " + Me.Mana + " Compare: " + System.Convert.ToDouble(Ini.GetString("paladin", "wisdompercent"))/100 + " )");
                    if (Me.Mana <= System.Convert.ToDouble(Ini.GetString("paladin", "wisdompercent")) / 100 &&
                        Ini.GetBoolean("paladin", "usejudgmentofwisdom", true))
                    {
                        if (judgmentofwisdom.canCast())
                        {
                            judgmentofwisdom.Cast();
                            continue;
                        }
                    }
                    //Runner w/ Low health?
                    if (Target.Health < .25 && Target.IsFacingAway)
                    {
                        if (judgmentofwisdom.canCast() && Ini.GetBoolean("paladin", "usejudgmentofjustice", true))
                        {
                            judgmentofjustice.Cast();
                            continue;
                        }
                    }
                    if (judgmentoflight.canCast())
                    {
                        judgmentoflight.Cast();
                        continue;
                    }
                }
                else
                {
                    if (judgmentoflight.canCast())
                    {
                        judgmentoflight.Cast();
                        continue;
                    }
                }//End Smart judgment

                //Smart Art of War
                if (Ini.GetBoolean("paladin", "enablesmartartofwar", true))
                {
                    bool buffFound = false;
                    Buff[] arraybuffs = Me.GetUnitBuffs();
                    foreach (Buff v in arraybuffs)
                    {
                        if (v.SpellID == 59578 || v.SpellID == 53489)
                        {
                            buffFound = Me.HasBuff(v.SpellID);
                        }
                    }
                    if (buffFound &&
                        Me.Health <= System.Convert.ToDouble(Ini.GetString("paladin", "flashpercent")) / 100 &&
                        Ini.GetBoolean("paladin", "useflashoflight", true))
                    {
                        if (flashoflight.canCast())
                        {
                            flashoflight.Cast(CastOptions.SelfTarget | CastOptions.FastReturn);
                            continue;
                        }
                    }
                    else if (buffFound &&
                             Ini.GetBoolean("paladin", "useexorcism", true))
                    {
                        if (exorsicm.canCast())
                        {
                            exorsicm.Cast(CastOptions.FastReturn);
                            continue;
                        }
                    }
                }//End Smart Art of War

                //Divine Storm
                if (divinestorm.canCast() && Ini.GetBoolean("paladin", "usedivinestorm", true))
                {
                    divinestorm.Cast();
                    continue;
                }//End Divine Storm

                //Consecration
                if (Ini.GetBoolean("paladin", "useconsecration", false))
                {
                    if (Ini.GetBoolean("paladin", "consecrationonadds", false) && extra != null)
                    {
                        if (consecration.canCast())
                        {
                            consecration.Cast();
                            continue;
                        }
                    }
                    if (!Ini.GetBoolean("paladin", "consecrationonadds", false))
                    {
                        if (consecration.canCast())
                        {
                            consecration.Cast();
                            continue;
                        }
                    }
                }//End Consecration

                //Hammer of Wrath
                if (hammerofwrath.canCast() &&
                    Ini.GetBoolean("paladin", "usehammerofwrath", true) &&
                    Target.Health < .20)
                {
                    hammerofwrath.Cast();
                    continue;
                }//End Hammer of Wrath


            }//End While
        }//End Combat
        #endregion
    }

}